本文同步分享於個人部落格:Liwen Chiou | Digital Architect & Full-Stack Engineer
孩子,在踏上今日的領地前,先坐下來喝杯酒吧。
修煉的路很長,別急著奔跑,先聽聽這份卷軸裡的古老叮嚀。我在每一站的盡頭都為你鋪設了 「
實戰演武場 CodePen」。那不只是程式碼的拼湊,而是你在這場暴風雨中,試圖用邏輯點燃的一顆星火。
成功突圍後,別忘了帶著你的戰利品回到 「QuestBoard 佈告欄」。在那裡,你會發現自己從不孤單,公會的夥伴們都正舉杯等待你的歸來。記住...
「 導師看重的從來不是你的劍法有多華麗,而是當你被邏輯擊潰、滿身泥濘後,依然選擇握緊理性的劍柄,再次向真相發起衝鋒的勇氣。 」
「新夥伴,這套『變色龍盔甲 (this)』是公會最有名的聖物。它的神奇之處在於,它沒有固定的顏色,也沒有固定的主人。」我指著大廳中央那套發著微光的盔甲。
當戰士穿上它時,它就變成紅色且聽從戰士命令;當法師穿上它時,它就轉為藍色且聽從法師調遣。最尷尬的是,如果這套盔甲被隨便丟在地上沒人穿,它就會預設聽從「公會長 (Window)」的命令。很多冒險者會被 this 搞瘋,是因為他們在找「這段代碼寫在哪裡」,但其實你該找的是:「現在是誰在用它?」。
在 JavaScript 的世界裡,this 的指向並不是在寫咒語時決定的,而是在 「發動咒語的瞬間(執行時)」 決定的。
obj.fn(),那麼點 . 前面的人就是主人。
const warrior = {
name: "艾冉",
attack() {
console.log(this.name);
},
};
warrior.attack(); // 輸出:艾冉 (點前面是 warrior)
fn(),它就預設屬於最高領袖 (Window)。
function shout() {
console.log(this);
}
shout(); // 輸出:Window
this,它直接繼承 「宣告時外層環境」 的主人。除了被動判定,我們也可以施展「契約魔法」來強制指定主人。
🏹 導師的辨析圖:契約魔法對照表
| 指令 | 動作說明 | 參數傳遞方式 | 是否立即執行 |
|---|---|---|---|
call() |
強制指定主人並啟動 | 逐一傳入 (arg1, arg2) |
✅ 是 |
apply() |
強制指定主人並啟動 | 陣列傳入 ([args]) |
✅ 是 |
bind() |
簽訂專屬契約 | 預先綁定,不啟動 | ❌ 否 |
導師的圖解心法:
this會隨著它的 「持有者」 不同而變幻色澤。就像一把神劍,拿在勇者手上,它閃耀著正義之光(指向勇者物件);但如果神劍被掉在地上或被暴徒撿走,它的光芒就會隨之改變(指向新的執行環境)。決定光芒的,不是寶劍本身,而是 「誰在揮舞它」。

const hero = {
name: "辛梅爾",
shout: function () {
console.log(`🛡️ 勇者:${this.name}`);
},
};
const talk = hero.shout; // ⚠️ 把咒語「單獨」儲存起來
talk(); // 輸出:🛡️ 勇者:undefined (因為 talk 前面沒點)
const hero = {
name: "辛梅爾",
shout: function () {
console.log(`🛡️ 勇者:${this.name}`);
},
};
// 🔒 預約咒語時,透過 bind 強行指定主人為 hero
const talk = hero.shout.bind(hero);
talk(); // 輸出:🛡️ 勇者:辛梅爾 (門牌已鎖死!)
這是開發中最常出錯的地方。當你把物件的方法交給「計時器」或「事件監聽器」執行時,this 往往會變回空空如也的 Window。
const mage = {
name: "辛梅爾",
greet() {
setTimeout(function () {
console.log(this.name); // 猜猜看是誰? (答案是:Window)
}, 100);
},
};
職人解法: 使用 Day 03 的箭頭函式,或者在此處進行 bind(this)。學會防止 this 遺失,是通往高階架構的必經之路。
孩子,導師看過無數冒險者在處理「點擊事件」時,一用
this就噴出錯誤。「你沒帶它出門,它就不是你的。」 很多人以為在物件裡寫了
this,這輩子它就跟定你了。錯!如果你把這個咒語單獨交給別人(傳入外部函式執行),它就失去了原本宿主對它的控制。記住:「如果你呼叫時失去了門牌號碼 (.),它的 this 就會瞬間易主。」
天色微亮,營火雖已燃盡,但你眼中卻閃爍著領悟的光芒。在前往演武場挑戰關卡前,我已經幫你把靈魂碎片精煉成了這份「戰術錦囊」。拿好它,今日的任務不再是負擔,而是你證明自我的舞台。去吧,公會的英雄榜在等著你的戰報。
obj.fn(),this 為 obj。fn(),this 為預設領袖 (Window)。call, apply, bind 強制決定歸屬。this 乖乖聽話,除了 bind 之外,還會用哪招(Day 03 箭頭函式)?